package by.yakusekmaxim.bookgid.webapp.page.admin.book;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;

import javax.inject.Inject;
import javax.persistence.metamodel.SingularAttribute;

import org.apache.wicket.Page;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
import org.apache.wicket.extensions.markup.html.repeater.util.SortableDataProvider;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.navigation.paging.PagingNavigator;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.ResourceModel;

import by.yakusekmaxim.bookgid.dataaccess.util.Filter;
import by.yakusekmaxim.bookgid.datamodel.Book;
import by.yakusekmaxim.bookgid.datamodel.Book_;
import by.yakusekmaxim.bookgid.datamodel.enums.PublicationStatus;
import by.yakusekmaxim.bookgid.services.BookService;
import by.yakusekmaxim.bookgid.webapp.page.admin.autor.EditAuthorPage;

public class BookListPanel extends Panel {

	@Inject
	BookService bookService;

	public BookListPanel(String id, Filter<Book> filter, final Page page) {
		super(id);

		BookDataProvider bookDataProvider = new BookDataProvider(filter);

		DataView<Book> dataView = new DataView<Book>("list", bookDataProvider,
				10) {
			@Override
			protected void populateItem(Item<Book> item) {
				final Book book = item.getModelObject();

				item.add(new Label("id"));
				item.add(new Label("name"));
				item.add(new Label("nameOr"));

				item.add(new Label("date", getDataFormat(book.getDate())));

				Link<Object> linkAuthor = new Link<Object>("linkAuthor") {
					@Override
					public void onClick() {

						setResponsePage(new EditAuthorPage(book.getAuthor(),
								page));

					}
				};

				linkAuthor.setEnabled(book.getAuthor() != null);

				linkAuthor.add(new Label("author", getAuthorName(book)));
				item.add(linkAuthor);
				item.add(new Label("genre", getGenreName(book)));
				item.add(new Label("series", getSeriesName(book)));
				item.add(new Label("status", getStatus(book)));
				item.add(new Link<Object>("edit") {
					@Override
					public void onClick() {
						 setResponsePage(new EditBookPage(book));
					}
				});
				
				item.add(new Link<Object>("delete") {
					@Override
					public void onClick() {
						bookService.delete(book);
						setResponsePage(page);
					}
				});
			}

		};

		add(dataView);

		add(new PagingNavigator("paging", dataView));

		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByID", Book_.id,
				bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByName",
				Book_.name, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByNameOr",
				Book_.nameOr, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByDate",
				Book_.date, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByAuthor",
				Book_.author, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByGenre",
				Book_.genre, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortBySeries",
				Book_.series, bookDataProvider));
		add(new OrderByBorder<SingularAttribute<Book, ?>>("sortByStatus",
				Book_.status, bookDataProvider));
		
	}

	private class BookDataProvider extends
			SortableDataProvider<Book, SingularAttribute<Book, ?>> {

		private Filter<Book> filter = new Filter<Book>();

		public BookDataProvider(Filter<Book> filter) {
			super();
			setSort(Book_.id, SortOrder.ASCENDING);
			this.filter = filter;

		}

		@Override
		public Iterator<? extends Book> iterator(long first, long count) {

			SingularAttribute<Book, ?> sortParam = getSort().getProperty();
			SortOrder propertySortOrder = getSortState().getPropertySortOrder(
					sortParam);
			boolean ascending = SortOrder.ASCENDING.equals(propertySortOrder);

			if (filter.getEnabled()) {
				return bookService.getAllBook(sortParam, ascending,
						(int) first, (int) count, filter).iterator();
			}
			return bookService.getAllBook(sortParam, ascending, (int) first,
					(int) count).iterator();
		}

		@Override
		public long size() {
			if (filter.getEnabled()) {
				return bookService.getCount(filter.getAttribute(),
						filter.getValue());
			}
			return bookService.getCount();
		}

		@Override
		public IModel<Book> model(Book book) {
			return new CompoundPropertyModel<Book>(book);
		}
	}

	private ResourceModel getStatus(Book book) {
		PublicationStatus statud = book.getStatus();

		if (statud == PublicationStatus.publicationstatus_edited) {
			return new ResourceModel("p.admin.author.status.edited");
		}

		if (statud == PublicationStatus.publicationstatus_published) {
			return new ResourceModel("p.admin.author.status.published");
		}

		if (statud == PublicationStatus.publicationstatus_validation) {
			return new ResourceModel("p.admin.author.status.validation");
		}

		return null;
	}

	private String getDataFormat(Date date) {
		if (date == null) {
			return "-";
		}
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
		return dateFormat.format(date);
	}

	private String getAuthorName(Book book) {
		if (book.getAuthor() == null) {
			return "-";
		}
		return book.getAuthor().getName();
	}
	
	private String getGenreName(Book book) {
		if (book.getGenre() == null) {
			return "-";
		}
		return book.getGenre().getName();
	}
	
	private String getSeriesName(Book book) {
		if (book.getSeries() == null) {
			return "-";
		}
		return book.getSeries().getName();
	}
}
